package pers.zifeng.distributed.lock.mysql.event;

import lombok.extern.slf4j.Slf4j;
import pers.zifeng.distributed.lock.mysql.service.MysqlDistributedLockService;

import java.lang.management.ManagementFactory;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author: zf
 * @date: 2021/05/17 15:31:14
 * @version: 1.0.0
 * @description: mysql分布式锁-乐观锁
 * 执行流程: 多进程抢购同一商品，每次抢购成功商品数量-1，商品数量为0时退出
 * 锁机制: 单一进程获取锁时则其他进程提交失败
 */
@Slf4j
public class OptimisticLock extends Thread {

    @Override
    public void run() {
        super.run();
        ResultSet resultSet = null;
        String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        String goodName = null;
        MysqlDistributedLockService.AutoCommit();
        int goodCount = 0;
        try {
            while (true) {
                log.info("当前线程:" + pid + ",开始抢购商品！");
                // 获取当前库存信息库存
                resultSet = MysqlDistributedLockService.getGoodCount(1);
                while (resultSet.next()) {
                    goodName = resultSet.getString("good_name");
                    goodCount = resultSet.getInt("good_count");
                }
                log.info("获取库存成功，当前商品名称为:" + goodName + ",当前库存剩余量为:" + goodCount);
                // 模拟执行业务事件
                Thread.sleep(2 * 1000);
                if (0 == goodCount) {
                    log.info("抢购失败，当前库存为0！");
                    break;
                }
                // 修改库存信息，库存量-1
                if (MysqlDistributedLockService.setGoodCount(1, goodCount)) {
                    log.info("当前线程:" + pid + " 抢购商品:" + goodName + "成功,剩余库存为:" + (goodCount - 1));
                    // 模拟延时，防止锁每次被同一进程获取
                    Thread.sleep(2 * 1000);
                } else {
                    log.error("抢购商品:" + goodName + "失败,商品数量已被修改！");
                }
            }
        } catch (Exception e) {
            log.error("抢购商品发生错误!", e);
        } finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException sqlException) {
                    log.error("关闭ResultSet失败！", sqlException);
                }
            }
            MysqlDistributedLockService.close();
        }
    }

    public static void main(String[] args) {
        new OptimisticLock().start();
    }

}
